package com.vast.admin.service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vast.admin.api.WechatApi;
import com.vast.admin.api.wechatpay.ParseReqInfo;
import com.vast.admin.api.wechatpay.WXPay;
import com.vast.admin.api.wechatpay.WXPayUtil;
import com.vast.admin.entity.Contract;
import com.vast.admin.entity.ContractDetail;
import com.vast.admin.entity.Customer;
import com.vast.admin.entity.WechatCallback;
import com.vast.admin.entity.weChat.WxContractDto;
import com.vast.admin.mapper.WechatCallbackMapper;
import com.vast.admin.service.impl.ContractRefundServiceImpl;
import com.vast.common.constant.MessageCode;
import com.vast.common.core.domain.Result;
import com.vast.system.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Service
@Slf4j
public class WechatCallbackService extends ServiceImpl<WechatCallbackMapper, WechatCallback> {

    @Autowired
    private ContractService contractService;

    @Autowired
    private CustomerService customerService;

    @Autowired
    private WechatApi wechatApi;

    @Autowired
    private ContractDetailService contractDetailService;

    @Autowired
    private ContractRefundServiceImpl contractRefundService;

    @Autowired
    private ParseReqInfo parseReqInfo;

    /**
     * 支付成功回调保存
     * @param content
     */
    public void save(String content) {
        try {
            WXPay wxPay = new WXPay(wechatApi.getWXPayConfig());
            Map<String, String> map = wxPay.processResponseXml(content);
            if (wxPay.isPayResultNotifySignatureValid(map)) {
                String orderNo = map.get("out_trade_no");
                contractService.completePay(orderNo);
            } else {
                throw new BusinessException("签名验证未通过");
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            WechatCallback wechatCallback = new WechatCallback();
            wechatCallback.setContent(content);
            wechatCallback.setCreateTime(new Date());
            super.save(wechatCallback);
        }
    }

    /**
     * 退款成功回调
     * @param content
     */
    public void refundCallback(String content) {
        try {
            Map<String, String> map = WXPayUtil.xmlToMap(content);
            if ("SUCCESS".equals(map.get("return_code"))) {
                String reqInfo = map.get("req_info");
                Map<String, String> reqInfoMap = WXPayUtil.xmlToMap(parseReqInfo.parseReqInfo(reqInfo));
                if ("SUCCESS".equals(reqInfoMap.get("refund_status"))) {
                    String outRefundNo = reqInfoMap.get("out_refund_no");
                    contractRefundService.wechatRefundCallback(outRefundNo);
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            WechatCallback wechatCallback = new WechatCallback();
            wechatCallback.setContent(content);
            wechatCallback.setCreateTime(new Date());
            super.save(wechatCallback);
        }

    }

    /**
     * 获取支付页面的信息
     * @param contractId
     * @param wxId
     * @return
     */
    public WxContractDto getContractInfo(Long contractId, String wxId) {
        Contract contract = contractService.getById(contractId);
        if (contract == null) {
            throw new BusinessException(new Result(MessageCode.ERROR, "未找到合同"));
        }
        Customer customer = customerService.getCustomerByWxId(wxId);
        if (contract == null) {
            throw new BusinessException(new Result(MessageCode.ERROR, "未找到用户信息"));
        }
        if (contract.getCustomerId().longValue() != customer.getId().longValue()) {
            throw new BusinessException(new Result(MessageCode.ERROR, "异常的合同信息"));
        }
        WxContractDto wxContractDto = new WxContractDto();
        BeanUtils.copyProperties(contract, wxContractDto);
        wxContractDto.setCustomerPhone(customer.getMobile());

        List<ContractDetail> contractDetails = contractDetailService.getByContractId(contractId);
        List<String> pdfPaths = new ArrayList<>(contractDetails.size());
        for (ContractDetail contractDetail : contractDetails) {
            pdfPaths.add(contractDetail.getPdfPath());
        }
        wxContractDto.setPdfPath(StringUtils.join(pdfPaths, ","));
        return wxContractDto;
    }

    /**
     * 下单
     * @param contractId
     * @param wxId
     * @return
     */
    public Map<String, String> prePay(Long contractId, String wxId) {
        Contract contract = contractService.getById(contractId);
        if (contract == null) {
            throw new BusinessException(new Result(MessageCode.ERROR, "未找到合同"));
        }
        if (contract.getIsPay().intValue() == 1) {
            throw new BusinessException(new Result(MessageCode.ERROR, "该合同订单已支付"));
        }
        Customer customer = customerService.getCustomerByWxId(wxId);
        if (contract == null) {
            throw new BusinessException(new Result(MessageCode.ERROR, "未找到用户信息"));
        }
        if (contract.getCustomerId().longValue() != customer.getId().longValue()) {
            throw new BusinessException(new Result(MessageCode.ERROR, "异常的合同信息"));
        }
        String wechatPayNo = contractService.getWechatPayOrderNo(contractId);
        Contract updateEntity = new Contract();
        updateEntity.setId(contractId);
        updateEntity.setWechatNo(wechatPayNo);
        contractService.updateById(updateEntity);
        return wechatApi.prePay(wechatApi.unifiedOrder(wechatPayNo, (long) (contract.getContractAmount() * 100), "59.174.166.72", wxId).get("prepay_id"));
    }

}
